package com.moon.game.service;

import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.moon.game.cache.Memcached;
import com.moon.game.constants.Constants;
import com.moon.game.constants.GlobalConstants;
import com.moon.game.manager.AnimalMG;
import com.moon.game.resource.model.Animal;
import com.moon.game.util.GDateUtils;
import com.moon.game.util.IDGenerator;
import com.moon.game.vos.PlayerVo;
import com.moon.game.vos.PlayerVo.Tower;
import com.moon.game.vos.RentLairBean;

/**
 * @description 巢穴【孵化塔】服务
 * @author Ranger 作者 E-mail:haozi000005@163.com
 * @version 创建时间：2012-7-6 下午2:08:14
 */
public class LairService {
	/**tower hierarchy, hierarchy<-->pro(min-max)*/
	public static HashMap<Integer, HashMap<Integer, int[]>> callProMap = new HashMap<Integer, HashMap<Integer,int[]>>();
	
	/**
	 * 巢穴（孵化塔）工厂
	 * 
	 * @param hierarchy
	 * @return
	 */
	public static Tower lairFactory(int hierarchy) {
		Tower tower = new Tower();
		tower.setCreateTime(GDateUtils.now());//铸造时间
		tower.setLastShowTime(GDateUtils.now());//最后一次访问时间
		tower.setLastRepariTime(GDateUtils.now());
		tower.setHierarchy(hierarchy);//巢穴等级，0凡兽,1仙兽,2神兽召唤巢穴
		tower.setTowerId(IDGenerator.generateIntId());//巢穴id
		tower.setEndure(100 * Constants.GAME_MULTIPLE);//持久
		tower.setCurrEndure(100 * Constants.GAME_MULTIPLE);//当前持久
		tower.setAnimalId(0);//巢穴里面动物的id，如果没有则为0
		return tower;
	}
	
	
	/**
	 * 召唤珍兽
	 * 
	 * @param tower
	 */
	public static Animal RefreashAnimal(Tower tower) {
		tower.setAnimalCalledTime(GDateUtils.now());
		int base = 0;
		Random random = new Random();
		switch(tower.getHierarchy()) {
			case 0:
				base = Constants.CALL_COMMON_ANIMAL_PRO;
				break;
			case 1:
				base = Constants.CALL_COMMON_ANIMAL_PRO + Constants.IMMORTAL_TOWER_CALL_IMMORTAL_ANIMAL_PRO;
				break;
			case 2:
				base = Constants.CALL_COMMON_ANIMAL_PRO + Constants.GOD_TOWER_CALL_IMMORTAL_ANIMAL_PRO + Constants.CALL_GOD_ANIMAL_PRO ;
				break;
		}
		Animal animal = null;
		List<Animal> res = null;
		switch(randomCall(tower.getHierarchy(), random.nextInt(base) + 1)) {
			case 0:
				res = AnimalMG.instance.getCommonAnimalList();
				break;
			case 1:
				res = AnimalMG.instance.getImmortalAnimalList();
				break;
			case 2:
				res = AnimalMG.instance.getGodAnimalList();
				break;
		}
		int callId = res.get(new Random().nextInt(res.size())).getId();
		tower.setAnimalId(callId);
		animal = AnimalMG.instance.animalFactory(callId);
		return animal;
	}
	
	/**
	 * 返回召唤到的珍兽类别【0凡兽，1仙兽，2神兽】
	 * 
	 * @param hierarchy
	 * @param value
	 * @return
	 */
	public static int randomCall(int hierarchy, int value) {
		if (callProMap.size() == 0) {
			loadCallPro();
		}
		
		int calledAnimal = 0;
		HashMap<Integer, int[]> hierarchyToProMap = callProMap.get(hierarchy);
		for (Map.Entry<Integer, int[]> entry : hierarchyToProMap.entrySet()) {
			int[] pro = entry.getValue();
			if (value >= pro[0] && value <= pro[1]) {
				calledAnimal = entry.getKey().intValue();
				break;
			}
		}
		return calledAnimal;
	}
	
	private static void loadCallPro() {
		int[] pro = new int[2];
		HashMap<Integer, int[]> hierarchyToProMap = new HashMap<Integer, int[]>();
		pro[0] = 1;
		pro[1] = Constants.CALL_COMMON_ANIMAL_PRO;
		packPut(pro, hierarchyToProMap, 0);//召唤凡兽概率
		callProMap.put(0, hierarchyToProMap);//凡兽塔召唤凡兽概率
		
		hierarchyToProMap = new HashMap<Integer, int[]>();
		pro[0] = 1;
		pro[1] = Constants.CALL_COMMON_ANIMAL_PRO;
		packPut(pro, hierarchyToProMap, 0);//召唤凡兽概率
		pro[0] = pro[1] + 1;
		pro[1] = pro[0] + Constants.IMMORTAL_TOWER_CALL_IMMORTAL_ANIMAL_PRO - 1;
		packPut(pro, hierarchyToProMap, 1);//召唤仙兽概率
		callProMap.put(1, hierarchyToProMap);//仙兽塔召唤仙兽概率
		
		hierarchyToProMap = new HashMap<Integer, int[]>();
		pro[0] = 1;
		pro[1] = Constants.CALL_COMMON_ANIMAL_PRO;
		packPut(pro, hierarchyToProMap, 0);//召唤凡兽概率
		pro[0] = pro[1] + 1;
		pro[1] = pro[0] + Constants.GOD_TOWER_CALL_IMMORTAL_ANIMAL_PRO - 1;
		packPut(pro, hierarchyToProMap, 1);//召唤仙兽概率
		pro[0] = pro[1] + 1;
		pro[1] = pro[0] + Constants.CALL_GOD_ANIMAL_PRO - 1;
		packPut(pro, hierarchyToProMap, 2);//召唤神兽概率
		callProMap.put(2, hierarchyToProMap);//神兽塔召唤珍兽概率
	}
	
	/**
	 * 包装put
	 * 
	 * @param pro
	 * @param hierarchyToProMap
	 * @param index
	 */
	private static void packPut(int[] pro, HashMap<Integer, int[]> hierarchyToProMap, int index) {
		int[] temp = new int[pro.length];
		for (int i = 0; i < temp.length; i++) {
			temp[i] = pro[i];
		}
		hierarchyToProMap.put(index, temp);
	}
	
	/**
	 * 获得修理费用
	 * 
	 * @param itemId
	 * @param currentEndure
	 * @return
	 */
	public static int getRepaireMoney(Tower tower) {
		int endure = tower.getEndure();
		int currentEndure = tower.getCurrEndure();
		return getRepaireMoney(endure - currentEndure, tower.getHierarchy());
	}
	
	
	/**
	 * 获得修理费用
	 * 
	 * @param lackEndure被侵蚀的持久
	 * @param hierarchy孵化塔品阶
	 * @return
	 */
	public static int getRepaireMoney(int lackEndure, int hierarchy) {
		int money = 0;
		// 计算花费的灵石
		if(hierarchy == 2) {
			money = ((5000 + hierarchy * 400) * 100 / 32000) * lackEndure * 2 / 1000;
		}else if (hierarchy == 1) {
			money = ((5000 + hierarchy * 200) * 90 / 32000) * lackEndure * 2 / 1000;
		}else {
			money = (5000 * 80 / 32000) * lackEndure / 1000;
		}
		return money;
	}
	
	/**
	 * 查找指定tower是否在tower列表中
	 * 
	 * @param towers
	 * @param towerId
	 * @return 在：返回tower，不在：返回null
	 */
	public static Tower findLair(List<Tower> towers, Integer towerId) {
		for (Tower tower : towers) {
			if (tower.getTowerId() == towerId.intValue()) {
				return tower;
			}
		}
		return null;
	}
	
	/**
	 * 持久消耗计算
	 * 
	 * @param tower
	 * @param mode 1表示孵化成功的持久消耗 2表示进入自然风蚀
	 * @param time 自然风蚀经历的时间
	 * @return
	 */
	public static int calcMinusLairEndure(int mode, int time) {
		if (mode == 1) {
			return Constants.ANIMAL_ERODE;
		}else {
			int erode = (int)(Constants.NATRUE_ERODE * time);
			//时间太长保护
			if (erode > 0) {
				erode = erode > 10000000 ? 10000000 : erode;
			}else {
				erode = 0;
			}
			return erode;
		}
	}
	
	
	/**
	 * 孵化塔按照孵化次数和id排序
	 * 
	 * @param rentTowers
	 * @return
	 */
	public static void sortRentLairBean(List<RentLairBean> rentTowers) {
		Comparator<RentLairBean> comparator = new Comparator<RentLairBean>() {
			public int compare(RentLairBean t1, RentLairBean t2) {
				// 先孵化次数
				if (t1.getTower().getIncubationTimes() != t2.getTower().getIncubationTimes()) {
					return t2.getTower().getIncubationTimes() - t1.getTower().getIncubationTimes();
				} else {
					// 再按id
					if (t1.getTower().getTowerId() != t2.getTower().getTowerId()) {
						return t1.getTower().getTowerId() - t2.getTower().getTowerId();
					}
				}
				return 0;
			}
		};
		
		Collections.sort(rentTowers,comparator);
	}
	
	
	/*public static void main(String[] args) {
		List<Tower> towers = new ArrayList<Tower>();
		List<RantLairBean> rantTowers = new ArrayList<RantLairBean>();
		for (int i = 0; i < 50; i++) {
			Tower tower = new Tower();
			tower.setAnimalCalledTime(9);
			tower.setTowerId(10 - i);
			towers.add(tower);
			RantLairBean bean = new RantLairBean(tower, i+"", i+"", 0);
			rantTowers.add(bean);
		}
		sortRantLairBean(rantTowers);
		SizeCalculator.calcSize((Serializable) rantTowers);
	}*/
	
	/**
	 * 查找指定的RantLairBean
	 * 
	 * @param player
	 * @param towerId
	 * @return 能够找到返回bean不能找到返回null
	 */
	public static RentLairBean findRendLairBean(LinkedList<RentLairBean> rentingLairs, PlayerVo player, int towerId) {
		if (rentingLairs == null || rentingLairs.size() == 0) {
			return null;
		}
		for (RentLairBean bean : rentingLairs) {
			if (player.getSid().equals(bean.getSid()) && player.getId().equals(bean.getPid()) && towerId == bean.getTower().getTowerId()) {
				return bean;
			}
		}
		return null;
	}
	
	/**
	 * 更新bean到Memcached
	 * 
	 * @param rentingLairs
	 * @param newBean
	 */
	public static void UpdataTheRendBean(LinkedList<RentLairBean> rentingLairs, RentLairBean newBean) {
		LinkedList<RentLairBean> newRentingLairs = new LinkedList<RentLairBean>();
		for (RentLairBean bean : rentingLairs) {
			if (bean.getTower().getStartRentTime() + bean.getTower().getRentTime() < GDateUtils.now()) {
				//出租过期的孵化塔
				continue;
			}
			if (newBean.getSid().equals(bean.getSid()) && newBean.getPid().equals(bean.getPid()) && newBean.getTower().getTowerId() == bean.getTower().getTowerId()) {
				newRentingLairs.addLast(newBean);
			}else {
				newRentingLairs.addLast(bean);
			}
		}
		String key = Constants.RENT_LAIR_EKY;
		Memcached.set(GlobalConstants.POOL_NAME_SYS, key, newRentingLairs);
	}
	
	/**
	 * 获取指定mode的出租列表
	 * 
	 * @param rentingLairs
	 * @param mode 0查看凡兽1查看仙兽2查看神兽-1查看全部
	 * @return 出租塔列表
	 */
	public static LinkedList<RentLairBean> rentingLairsFilter(LinkedList<RentLairBean> rentingLairs, int mode) {
		if (mode == -1) {
			return rentingLairs;
		}else {
			LinkedList<RentLairBean> beans = new LinkedList<RentLairBean>();
			if (rentingLairs != null && rentingLairs.size() > 0) {
				for (RentLairBean bean : rentingLairs) {
					final Animal animal = AnimalMG.instance.getAnimal(bean.getTower().getAnimalId());
					if (animal != null && animal.getHierarchy() == mode) {
						beans.addLast(bean);
					}
				}
			}
			return beans;
		}
		
	}
	
	/**
	 * 获取正在出租的孵化塔
	 * 
	 * @return
	 */
	public static LinkedList<RentLairBean> getRentingLairs() {
		String key = Constants.RENT_LAIR_EKY;
		LinkedList<RentLairBean> rentingLairs = (LinkedList<RentLairBean>) Memcached.get(GlobalConstants.POOL_NAME_SYS, key);
		if (rentingLairs == null) {
			rentingLairs = new LinkedList<RentLairBean>();
		}
		if (rentingLairs.size() > 1) {
			//长度大于1按照成功召唤顺序，id顺序排列
			sortRentLairBean(rentingLairs);
		}
		LinkedList<RentLairBean> newRentingLairs = new LinkedList<RentLairBean>();
		for (RentLairBean bean : rentingLairs) {
//			System.err.println(GDateUtils.formatFromLong((bean.getTower().getStartRentTime() + bean.getTower().getRentTime()) * 1000l, "yyyy年MM月dd日 HH时mm分ss"));
			if (checkRentingLairPassTime(bean.getTower())) {
				//出租过期的孵化塔
				continue;
			}
			newRentingLairs.addLast(bean);
		}
		Memcached.set(GlobalConstants.POOL_NAME_SYS, key, newRentingLairs);
		return newRentingLairs;
	}
	
	/**
	 * 检测指定孵化塔是否过期
	 * 
	 * @param tower
	 * @return true过期，false未过期
	 */
	public static boolean checkRentingLairPassTime(Tower tower) {
		if (tower.getStartRentTime() + tower.getRentTime() < GDateUtils.now()) {
			//出租过期的孵化塔
			return true;
		}
		return false;
	}
	
	/**
	 * 取消指定孵化塔的出租
	 * 
	 * @param tower
	 */
	public static void cancelTheRentingTower(Tower tower) {
		tower.setStartRentTime(0);
		tower.setRentTime(0);
		LinkedList<RentLairBean> rentingLairs = getRentingLairs();
		if (rentingLairs == null || rentingLairs.size() == 0) {
			return;
		}else {
			LinkedList<RentLairBean> newRentingLairs = new LinkedList<RentLairBean>();
			for (RentLairBean bean : rentingLairs) {
				if (bean.getTower().getTowerId() == tower.getTowerId()) {
					continue;
				}
				if (checkRentingLairPassTime(bean.getTower())) {
					//过期孵化塔
					continue;
				}
				newRentingLairs.addLast(bean);
			}
			
			//更新到Memcached
			String key = Constants.RENT_LAIR_EKY;
			Memcached.set(GlobalConstants.POOL_NAME_SYS, key, newRentingLairs);
		}
	}
	
	/**
	 * 出租孵化塔
	 * 
	 * @param tower
	 * @param player
	 * @param incubationPrice指定孵化价格
	 * @return -2表示目前已经在出租；-1出租成功，其他时间表示最短过期的时间【秒】
	 */
	public static int rentingLair(Tower tower, PlayerVo player, int incubationPrice) {
		LinkedList<RentLairBean> rentingLairs = getRentingLairs();
		if (rentingLairs == null) {
			rentingLairs = new LinkedList<RentLairBean>();
		}else {
			for (RentLairBean bean : rentingLairs) {
				if (bean.getTower().getTowerId() == tower.getTowerId()) {
					return -2;
				}
			}
		}
		
		if (rentingLairs.size() >= Constants.SYS_RENT_LAIR_CAPACITY) {
			//超过出租容量。返回最快一个还有多久到期
			int minExpired = 0;
			for (RentLairBean bean : rentingLairs) {
				Tower theTower = bean.getTower();
				if (theTower.getStartRentTime() + theTower.getRentTime() > minExpired) {
					minExpired = theTower.getStartRentTime() + theTower.getRentTime();
				}
			}
			
			return minExpired - GDateUtils.now();
		}else {
			tower.setStartRentTime(GDateUtils.now());
			tower.setRentTime(Constants.RENT_LAIR_DEFAULT_TIME);
			rentingLairs.add(new RentLairBean(tower, player.getSid(), player.getId(), incubationPrice, player.getName(), player.getSex()));
			if (rentingLairs.size() > 1) {
				//长度大于1按照成功召唤顺序，id顺序排列
				sortRentLairBean(rentingLairs);
			}
			String key = Constants.RENT_LAIR_EKY;
			Memcached.set(GlobalConstants.POOL_NAME_SYS, key, rentingLairs);
			return -1;
		}
	}
	
	/**
	 * 出租bean
	 * 
	 * @author Ranger
	 *
	 */
	public static class RantLairBean1 implements Serializable{
		private Tower tower;
		private String sid;
		private String pid;
		private String hostName;//出租者的姓名
		private int sex;//出租者的性别
		private int incubationPrice;
		private int rentingTimes = 0;//续租次数，正常出租此值为0
		
		/**
		 * @param tower
		 * @param sid
		 * @param pid
		 * @param incubationPrice
		 * @param hostName
		 * @param sex
		 */
		public RantLairBean1(Tower tower, String sid, String pid, int incubationPrice, String hostName, int sex) {
			this.tower = tower;
			this.sid = sid;
			this.pid = pid;
			this.hostName = hostName;
			this.sex = sex;
			this.incubationPrice = incubationPrice;
		}
		public Tower getTower() {
			return tower;
		}
		public void setTower(Tower tower) {
			this.tower = tower;
		}
		public String getSid() {
			return sid;
		}
		public void setSid(String sid) {
			this.sid = sid;
		}
		public String getPid() {
			return pid;
		}
		public void setPid(String pid) {
			this.pid = pid;
		}
		public String getHostName() {
			return hostName;
		}
		public void setHostName(String hostName) {
			this.hostName = hostName;
		}
		public int getSex() {
			return sex;
		}
		public void setSex(int sex) {
			this.sex = sex;
		}
		public int getIncubationPrice() {
			return incubationPrice;
		}
		public void setIncubationPrice(int incubationPrice) {
			this.incubationPrice = incubationPrice;
		}
		public int getRentingTimes() {
			return rentingTimes;
		}
		public void addRentingTimes() {
			rentingTimes ++;
		}
	}
	
	
	public static void main(String[] args) {
		System.out.println(GDateUtils.now()- 1344074716 - 18000);
	}
}
